{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bc1eba40",
   "metadata": {},
   "source": [
    "## AJAX 概述"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8636a1df",
   "metadata": {},
   "source": [
    "AJAX 即“Asynchronous Javascript And XML”（异步 JavaScript 和 XML）\n",
    "\n",
    "是指一种创建交互式、快速动态网页应用的网页开发技术，无需重新加载整个网页的情况下，能够更新部分网页的技术"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "361edaae",
   "metadata": {},
   "source": [
    "AJAX 相当于浏览器发送请求与接收响应的代理人，以实现在不影响浏览页面的情况下，局部更新页面数据，从而提高用户体验\n",
    "\n",
    "![](05_AJAX_images/01.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf3b3aae",
   "metadata": {},
   "source": [
    "## AJAX 基本使用"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5ca7c9b",
   "metadata": {},
   "source": [
    "具体见：AJAX/01_AJAX的基本使用.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f24a16c0",
   "metadata": {},
   "source": [
    "**1. 创建AJAX XMLHttpRequest 对象**\n",
    "```js\n",
    "let xhr = new XMLHttpRequest()\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e6ac565",
   "metadata": {},
   "source": [
    "**2. 设置AJAX请求地址以及请求方式**\n",
    "- 通过 XMLHttpRequest.open() 方法用于指定 HTTP 请求的参数，或者说初始化 XMLHttpRequest 实例对象。\n",
    "- 它一共可以接受五个参数\n",
    "```js\n",
    "void open(\n",
    "    string method, // 表示 HTTP 动词方法，比如 GET、POST、PUT、DELETE、HEAD\n",
    "    string url, // 表示请求发送目标 URL\n",
    "    \n",
    "    // 布尔值，表示请求是否为异步，默认为 true，\n",
    "    // 如果设为 false ，则 send 方法只有等到收到服务器返回了结果，才会进行下一步操作。\n",
    "    optional boolean async, \n",
    "    optional string user, // 表示用于认证的用户名，默认为空字符串。该参数可选\n",
    "    optional string password // 表示用于认证的密码，默认为空字符串。该参数可选。\n",
    ");\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94801de6",
   "metadata": {},
   "source": [
    "**3. 发送请求**\n",
    "- XMLHttpRequest.send() 方法用于实际发出 HTTP 请求。\n",
    "- 它的参数是可选的，如果不带参数，就表示 HTTP 请求只包含头信息，也就是只有一个 URL，典型例子就是 GET 请求；\n",
    "- 如果带有参数，就表示除了头信息，还带有包含具体数据的信息体，典型例子就是POST 请求\n",
    "```js\n",
    "xhr.send()\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d9c4dbb",
   "metadata": {},
   "source": [
    "**4. 获取服务器端给客户端的响应数据**\n",
    "- XMLHttpRequest 对象可以对以下事件指定监听函数\n",
    "    - XMLHttpRequest.onloadstart：loadstart 事件（HTTP 请求发出）的监听函数\n",
    "    - XMLHttpRequest.onprogress：progress事件（正在发送和加载数据）的监听函数\n",
    "    - XMLHttpRequest.onabort：abort 事件（请求中止，比如用户调用了 abort() 方法）的监听函数\n",
    "    - XMLHttpRequest.onerror：error 事件（请求失败）的监听函数\n",
    "    - XMLHttpRequest.onload：load 事件（请求成功完成）的监听函数\n",
    "    - XMLHttpRequest.ontimeout：timeout 事件（用户指定的时限超过了，请求还未完成）的监听函数\n",
    "    - XMLHttpRequest.onloadend：loadend 事件（请求完成，不管成功或失败）的监听函数\n",
    "    - XMLHttpRequest.onreadystatechange: readystatechange事件(当 readyState 属性变化)的监听函数\n",
    "    \n",
    "```js\n",
    "xhr.onload = function() {\n",
    "    console.log(xhr.responseText)\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "475aa02c",
   "metadata": {},
   "source": [
    "## AJAX get请求参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d2b7a4c",
   "metadata": {},
   "source": [
    "具体见：AJAX/02_AJAX的GET请求参数.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c78439a0",
   "metadata": {},
   "source": [
    "在get请求中，参数是拼接在url中的，所以此时可以获取到参数，拼接到url即可"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82cac5be",
   "metadata": {},
   "source": [
    "```js\n",
    "// 1、创建AJAX对象\n",
    "let xhr = new XMLHttpRequest()\n",
    "\n",
    "// 2、设置url\n",
    "url = 'http://httpbin.org/get'\n",
    "\n",
    "// 3、拼接请求参数\n",
    "args = '?uname=sxt&pwd=123'\n",
    "url = url + args\n",
    "\n",
    "// 4、设置请求的参数\n",
    "xhr.open('GET', url) // 不能设置条件的过滤参数\n",
    "\n",
    "// 5、发送请求\n",
    "xhr.send()  // get 请求不能在send中传递请求参数\n",
    "\n",
    "// 6、获取响应数据\n",
    "xhr.onload = () => {\n",
    "    console.log(xhr.responseText)\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de59e547",
   "metadata": {},
   "source": [
    "## AJAX post的使用"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29fe80b9",
   "metadata": {},
   "source": [
    "具体见：AJAX/03_AJAX的POST请求参数.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da344e81",
   "metadata": {},
   "source": [
    "AJAX使用post请求在传参时，参数应该放在body中，并通过 XMLHttpRequest.setRequestHeader() 设置请求信息的格式\n",
    "\n",
    "XMLHttpRequest.setRequestHeader() 方法用于设置浏览器发送的 HTTP 请求的头信息。\n",
    "\n",
    "该方法接受两个参数。第一个参数是字符串，表示头信息的字段名，第二个参数是字段值\n",
    "\n",
    "注意：\n",
    "- XMLHttpRequest.setRequestHeader() 该方法必须在 open() 之后、 send() 之前调用。\n",
    "- 如果该方法多次调用，设定同一个字段，则每一次调用的值会被合并成一个单一的值发送。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94e75649",
   "metadata": {},
   "source": [
    "**方式一：**\n",
    "```js\n",
    "// 拼接参数\n",
    "args = 'uname=' + uname + '&pwd=' + pwd\n",
    "\n",
    "// 创建xhr对象\n",
    "let xhr = new XMLHttpRequest()\n",
    "\n",
    "// 设置请求的方式与请求地址\n",
    "xhr.open('POST', 'http://httpbin.org/post')\n",
    "\n",
    "// 设置请求内容的类型(推荐)\n",
    "xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')\n",
    "\n",
    "// 发送请求\n",
    "xhr.send(args)\n",
    "\n",
    "// 获取服务器响应\n",
    "xhr.onload = () => {\n",
    "    console.log(xhr.responseText)\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d82f34e",
   "metadata": {},
   "source": [
    "**方式二：**\n",
    "```js\n",
    "// 拼接参数\n",
    "args = {'uname': uname, 'pwd': pwd}\n",
    "args = JSON.stringify(args)\n",
    "\n",
    "// 创建xhr对象\n",
    "let xhr = new XMLHttpRequest()\n",
    "\n",
    "// 设置请求的方式与请求地址\n",
    "xhr.open('POST', 'http://httpbin.org/post')\n",
    "\n",
    "// 设置请求内容的类型(推荐)\n",
    "xhr.setRequestHeader('Content-Type', 'application/json')\n",
    "\n",
    "// 发送请求\n",
    "xhr.send(args)\n",
    "\n",
    "// 获取服务器响应\n",
    "xhr.onload = () => {\n",
    "    console.log(xhr.responseText)\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbf06fe8",
   "metadata": {},
   "source": [
    "## 获取 服务器响应"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e1a2a12d",
   "metadata": {},
   "source": [
    "![](05_AJAX_images/02.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ae941e5",
   "metadata": {},
   "source": [
    "具体见：AJAX/04_AJAX状态码与响应处理.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8675be4",
   "metadata": {},
   "source": [
    "### AJAX 状态码"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26384f21",
   "metadata": {},
   "source": [
    "在创建AJAX对象，配置AJAX对象，发送请求，以及接收完服务器端响应数据，这个过程中的每一个步骤都会对应一个数值，这个数据就是AJAX状态码\n",
    "\n",
    "XMLHttpRequest.readyState 返回一个整数，表示实例对象的当前状态，该属性只读，它可能返回以下值：\n",
    "- 0: 表示 XMLHttpRequest 实例已经生成，但是实例的 open() 方法还没有被调用。\n",
    "- 1: 表示 open() 方法已经调用，但是实例的 send() 方法还没有调用，仍然可以使用实例的 setRequestHeader() 方法，设定 HTTP 请求的头信息。\n",
    "- 2: 表示实例的 send() 方法已经调用，并且服务器返回的头信息和状态码已经收到。\n",
    "- 3: 表示正在接收服务器传来的数据体（body 部分）这时，如果实例的 responseType 属性等于 text 或者空字符串， responseText 属性就会包含已经收到的部分信息\n",
    "- 4: 表示服务器返回的数据已经完全接收，或者本次接收已经失败。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c75d79d1",
   "metadata": {},
   "source": [
    "### HTTP 状态码\n",
    "XMLHttpRequest.status 属性返回一个整数，表示服务器回应的 HTTP 状态码。\n",
    "\n",
    "一般来说，如果通信成功的话，这个状态码是200；如果服务器没有返回状态码，那么这个属性默认是200。\n",
    "\n",
    "请求发出之前，该属性为 0 。该属性只读在 XMLHttpRequest.onreadystatechange 事件中,\n",
    "\n",
    "我们规定当服务器响应已做好被处理的准备时, 再执行任务"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "802fd9c4",
   "metadata": {},
   "source": [
    "### 响应数据的格式"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7df0151",
   "metadata": {},
   "source": [
    "服务器端大多数情况下会以JSON对象作为响应数据的格式。\n",
    "\n",
    "在http请求与响应的过程中，无论是请求参数还是响应内容，如果是对象类型，一般都会被转换为对象字符串进行传输\n",
    "```js\n",
    "JSON.parse() // 将 json字符串 转换为 json对象\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09cf0963",
   "metadata": {},
   "source": [
    "```js\n",
    "// 创建xhr对象\n",
    "let xhr = new XMLHttpRequest()\n",
    "\n",
    "// 设置请求的方式与请求地址\n",
    "xhr.open('get', 'http://httpbin.org/get')\n",
    "\n",
    "// 发送请求\n",
    "xhr.send()\n",
    "\n",
    "// 获取服务器响应\n",
    "xhr.onreadystatechange = () => {\n",
    "\n",
    "    // 判断ajax状态码是否为4\n",
    "    if (xhr.readyState == 4) {\n",
    "\n",
    "        // 判断Http状态码是否为200\n",
    "        if (xhr.status == 200) {\n",
    "            // 将数据转换成json类型\n",
    "            data = JSON.parse(xhr.responseText)\n",
    "            console.log(data)\n",
    "        }\n",
    "        else {\n",
    "            // 如果没有正常响应做出处理\n",
    "            console.log(xhr.status)\n",
    "        }\n",
    "    }\n",
    "    else {\n",
    "        console.log(xhr.readyState)\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7dadd91",
   "metadata": {},
   "source": [
    "## AJAX 错误处理"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "24d67ba3",
   "metadata": {},
   "source": [
    "![](05_AJAX_images/03.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e976b1f",
   "metadata": {},
   "source": [
    "具体见：AJAX/05_AJAX请求失败处理.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18633887",
   "metadata": {},
   "source": [
    "网络畅通，服务器端能接收到请求，服务器端返回的结果不是预期的结果。\n",
    "\n",
    "可以判断服务器端返回的状态码，分别进行处理。xhr.status 获取 http状态码\n",
    "- 网络畅通，服务器端没有接收到请求，返回404状态。检查请求地址是否错误\n",
    "- 网络畅通，服务器端能接收到请求，服务器端返回500状态码\n",
    "- 网络中断，请求无法发送到服务器端"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99c1977b",
   "metadata": {},
   "source": [
    "在AJAX中设置一个专门处理请求失败的监听函数 XMLHttpRequest.onerror ：error 事件（请求失败）的监听函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb945a03",
   "metadata": {},
   "source": [
    "```js\n",
    "// 请求失败了监听函数\n",
    "xhr.onerror = () =>{\n",
    "    console.log('网络中断了')\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65c24dcb",
   "metadata": {},
   "source": [
    "## AJAX 封装"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3233f982",
   "metadata": {},
   "source": [
    "\n",
    "发送一次请求代码过多，发送多次就会请求代码冗余重复\n",
    "- 将请求代码封装到函数中，发请求时调用函数即可"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e5402b6",
   "metadata": {},
   "source": [
    "### 简单封装"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb222995",
   "metadata": {},
   "source": [
    "具体见：AJAX/06_AJAX简单封装.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af7a2eb0",
   "metadata": {},
   "source": [
    "```js\n",
    "function AJAX(options){\n",
    "    // options 是一个json数据 , 包含type\\url\n",
    "\n",
    "    // 创建一个XHR对象\n",
    "    let xhr  = new XMLHttpRequest()\n",
    "\n",
    "    // 配置请求\n",
    "    xhr.open(options.type, options.url)\n",
    "\n",
    "    // 发送请求\n",
    "    xhr.send()\n",
    "\n",
    "    // 获取响应\n",
    "    xhr.onreadystatechange = ()=>{\n",
    "        // 判断是否完成请求\n",
    "        if (xhr.readyState == 4 && xhr.status == 200){\n",
    "            console.log(xhr.responseText)\n",
    "        }\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "055c8f9d",
   "metadata": {},
   "source": [
    "```js\n",
    "function get_data(){\n",
    "    AJAX({\n",
    "        type:'get',\n",
    "        url:'http://httpbin.org/get'\n",
    "    })\n",
    "\n",
    "    AJAX({\n",
    "        type:'post',\n",
    "        url:'http://httpbin.org/post'\n",
    "    })\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c07feffa",
   "metadata": {},
   "source": [
    "### 请求参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9ed9c5f",
   "metadata": {},
   "source": [
    "![](05_AJAX_images/04.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85feca72",
   "metadata": {},
   "source": [
    "具体见：AJAX/07_AJAX封装_请求参数.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd925ac5",
   "metadata": {},
   "source": [
    "因为 get请求 与 post请求 传递参数不同，因此我们根据不同的请求方式修改代码"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db074841",
   "metadata": {},
   "source": [
    "```js\n",
    "function AJAX(options){\n",
    "    /**\n",
    "     * options:\n",
    "     *  type: 请求的方式\n",
    "     *  url: 请求的地址\n",
    "     *  data: 请求的参数，类型是JSON\n",
    "    */\n",
    "\n",
    "    // 创建 AJAX对象\n",
    "    let xhr = new XMLHttpRequest()\n",
    "\n",
    "    // 处理请求的参数\n",
    "    let params = ''\n",
    "    for(let key in options.data){\n",
    "        value = options.data[key]\n",
    "        \n",
    "        // name=sxt&\n",
    "        params = params + key + '=' + value + '&'\n",
    "    }\n",
    "\n",
    "    // 去掉最后一个&\n",
    "    params = params.substr(0, params.length-1)\n",
    "\n",
    "    // get请求拼接参数（传递参数）\n",
    "    if(options.type === 'get'){\n",
    "        options.url = options.url + '?' + params\n",
    "    }\n",
    "\n",
    "    // 配置请求\n",
    "    xhr.open(options.type, options.url)\n",
    "\n",
    "    // post传递参数\n",
    "    if(options.type === 'post'){\n",
    "        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')\n",
    "        xhr.send(params)\n",
    "    }else{\n",
    "        xhr.send()\n",
    "    }\n",
    "\n",
    "    // 获取响应\n",
    "    xhr.onreadystatechange = ()=>{\n",
    "        if (xhr.readyState === 4 && xhr.status === 200){\n",
    "            console.log(xhr.responseText)\n",
    "        }\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc8c21ca",
   "metadata": {},
   "source": [
    "```js\n",
    "function get_data_get(){\n",
    "    AJAX({\n",
    "       type:\"get\",\n",
    "       url:\"http://httpbin.org/get\",\n",
    "       data:{\"name\":\"sxt\",\"pwd\":123}\n",
    "    })\n",
    "}\n",
    "\n",
    "function get_data_post(){\n",
    "    AJAX({\n",
    "       type:\"post\",\n",
    "       url:\"http://httpbin.org/post\",\n",
    "       data:{\"name\":\"sxt\",\"pwd\":123}\n",
    "    })\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3dd13393",
   "metadata": {},
   "source": [
    "### 处理响应"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db9867d6",
   "metadata": {},
   "source": [
    "当 AJAX 发送了请求后，AJAX 都应该回馈一个内容。这时就会分如下2个情况:\n",
    "\n",
    "#### 失败处理\n",
    "\n",
    "可以通过 onerror监听函数 处理错误情况，代码如下："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e333d806",
   "metadata": {},
   "source": [
    "```js\n",
    "// 网络请求失败\n",
    "xhr.onerror = ()=>{\n",
    "    options.error('1000:网络错误')\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1f6af36",
   "metadata": {},
   "source": [
    "#### 处理返回数据\n",
    "\n",
    "请求成功能可以，通过 onreadystatechange监听函数 处理。以下是可以使用的属性:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "600db48a",
   "metadata": {},
   "source": [
    "**XMLHttpRequest.response**\n",
    "\n",
    "- XMLHttpRequest.response 属性表示服务器返回的数据体（即 HTTP 回应的 body 部分）\n",
    "\n",
    "- 它可能是任何数据类型，比如字符串、对象、二进制对象等等，具体的类型由XMLHttpRequest.responseType 属性决定。\n",
    "\n",
    "- 该属性只读，如果本次请求没有成功或者数据不完整，该属性等于 null 。\n",
    "\n",
    "- 但是，如果 responseType 属性等于 text 或空字符串，在请求没有结束之前（ readyState 等于3的阶段）， response 属性包含服务器已经返回的部分数据。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53f1f92d",
   "metadata": {},
   "source": [
    "**XMLHttpRequest.responseType**\n",
    "- XMLHttpRequest.responseType 属性是一个字符串，表示服务器返回数据的类型。\n",
    "- 这个属性是可写的，可以在调用 open() 方法之后、调用 send() 方法之前，设置这个属性的值，告诉服务器返回指定类型的数据。\n",
    "- 如果 responseType 设为空字符串，就等同于默认值 text 。\n",
    "- XMLHttpRequest.responseType 属性可以等于以下值：\n",
    "    1. ”“（空字符串）：等同于 text ，表示服务器返回文本数据。\n",
    "    2. “arraybuffer”：ArrayBuffer 对象，表示服务器返回二进制数组。\n",
    "    3. “blob”：Blob 对象，表示服务器返回二进制对象，比如图片文件\n",
    "    4. “document”：Document 对象，表示服务器返回一个文档对象，适合返回 HTML / XML 文档\n",
    "    5. “json”：JSON 对象。\n",
    "    6. “text”：字符串。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdcfa723",
   "metadata": {},
   "source": [
    "**XMLHttpRequest.responseText**\n",
    "- XMLHttpRequest.responseText 属性返回从服务器接收到的字符串，该属性为只读。\n",
    "- 只有 HTTP 请求完成接收以后，该属性才会包含完整的数据"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "325e67f0",
   "metadata": {},
   "source": [
    "```js\n",
    " // 接收响应\n",
    "xhr.onreadystatechange = () => {\n",
    "    if (xhr.readyState === 4) {\n",
    "        if (xhr.status === 200) {\n",
    "            options.success(xhr.responseText)\n",
    "        } else {\n",
    "            options.error(xhr.status);\n",
    "        }\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebff468c",
   "metadata": {},
   "source": [
    "**XMLHttpRequest.responseXML**\n",
    "- XMLHttpRequest.responseXML 属性返回从服务器接收到的 HTML 或 XML 文档对象，该属性为只读。\n",
    "- 如果本次请求没有成功，或者收到的数据不能被解析为 XML 或 HTML，该属性等于null 。\n",
    "- 该属性生效的前提是 HTTP 回应的 Content-Type 头信息等于 text/xml 或 application/xml 。\n",
    "- 这要求在发送请求前， XMLHttpRequest.responseType 属性要设为 document 。\n",
    "- 如果 HTTP 回应的 Content-Type 头信息不等于 text/xml 和 application/xml ，但是想从 responseXML 拿到数据（即把数据按照 DOM 格式解析），那么需要手动调用 XMLHttpRequest.overrideMimeType() 方法，强制进行 XML 解析。\n",
    "- 该属性得到的数据，是直接解析后的文档 DOM 树。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e14133c",
   "metadata": {},
   "source": [
    "**XMLHttpRequest.responseURL**\n",
    "- XMLHttpRequest.responseURL 属性是字符串，表示发送数据的服务器的网址\n",
    "- 注意：这个属性的值与 open() 方法指定的请求网址不一定相同。\n",
    "- 如果服务器端发生跳转，这个属性返回最后实际返回数据的网址。另外，如果原始 URL 包括锚点（fragment），该属性会把锚点剥离。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6eaffc41",
   "metadata": {},
   "source": [
    "### 设置默认参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d5e1195",
   "metadata": {},
   "source": [
    "具体见：AJAX/09_AJAX封装_默认参数.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98c2b61f",
   "metadata": {},
   "source": [
    "在使用AJAX时，往往需要传递多个参数。为了简化使用封装的AJAX方法，因此可以考虑给AJAX方法设置默认参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "210577bd",
   "metadata": {},
   "source": [
    "```js\n",
    "function ajax(options) {\n",
    "    /**\n",
    "     * options:\n",
    "     *  type: 请求的方式\n",
    "     *  url: 请求的地址\n",
    "     *  data: 请求的参数，类型是JSON\n",
    "     *  success: 请求成功以后，如何处理,函数\n",
    "     *  error: 请求失败以后，如何处理,函数\n",
    "    */\n",
    "    let defaults ={\n",
    "        type:'get',\n",
    "        url:'',\n",
    "        success:()=>{},\n",
    "        error:()=>{}\n",
    "    }\n",
    "    // 将options的参数值覆盖到defaults里\n",
    "    Object.assign(defaults, options)\n",
    "    .....\n",
    "}\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fad21603",
   "metadata": {},
   "source": [
    "```js\n",
    "function get_data(){\n",
    "    ajax({\n",
    "        // type:'get',\n",
    "        url:'http://httpbin.org/get',\n",
    "        success:(data)=>{\n",
    "            console.log(data)\n",
    "        }\n",
    "    })\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0c4a634",
   "metadata": {},
   "source": [
    "## jQuery 中的 AJAX"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "392acda4",
   "metadata": {},
   "source": [
    "具体见：AJAX/10_JQuery中使用AJAX.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "459a4b46",
   "metadata": {},
   "source": [
    "在JQuery中，为我们封装了AJAX的方法，有以下几个参数:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ffd1412",
   "metadata": {},
   "source": [
    "jQuery.AJAX([settings])\n",
    "\n",
    "        – type\n",
    "        – url\n",
    "        – data\n",
    "        – contentType\n",
    "        – beforSend 发送请求前可修改 XMLHttpRequest 对象的函数，如添加自定义 HTTP 头\n",
    "        – success\n",
    "        – error"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c588ddad",
   "metadata": {},
   "source": [
    "### JSON 形式的参数传递"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6316400",
   "metadata": {},
   "source": [
    "```js\n",
    "function test_get_args_json(){\n",
    "    $.ajax({\n",
    "        type:'get',\n",
    "        url:'http://httpbin.org/get',\n",
    "        data:{\"name\":\"sxt\",\"pwd\":123},\n",
    "        success:(data)=>{\n",
    "            console.log(data)\n",
    "        }\n",
    "    }) \n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c46daa6",
   "metadata": {},
   "source": [
    "```js\n",
    "function test_post_args_json(){\n",
    "    $.ajax({\n",
    "        type:'post',\n",
    "        url:'http://httpbin.org/post',\n",
    "        data:{\"name\":\"sxt\",\"pwd\":123},\n",
    "        success:(data)=>{\n",
    "            console.log(data)\n",
    "        }\n",
    "    }) \n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30ca17cb",
   "metadata": {},
   "source": [
    "### str 的形式参数传递"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb1c76af",
   "metadata": {},
   "source": [
    "```js\n",
    "function test_get_args_str(){\n",
    "    $.ajax({\n",
    "        type:'get',\n",
    "        url:'http://httpbin.org/get',\n",
    "        data:'name=sxt&pwd=123',\n",
    "        success:(data)=>{\n",
    "            console.log(data)\n",
    "        }\n",
    "    }) \n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71e74f51",
   "metadata": {},
   "source": [
    "```js\n",
    "function test_post_args_str(){\n",
    "   $.ajax({\n",
    "       type:'post',\n",
    "       url:'http://httpbin.org/post',\n",
    "       data:'name=sxt&pwd=123',\n",
    "       success:(data)=>{\n",
    "           console.log(data)\n",
    "       }\n",
    "   }) \n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e48b6891",
   "metadata": {},
   "source": [
    "### 服务器要求传递JSON"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ac6b3cf",
   "metadata": {},
   "source": [
    "```js\n",
    "function test_post_args_json2(){\n",
    "    $.ajax({\n",
    "        type:'post',\n",
    "        url:'http://httpbin.org/post',\n",
    "        data:{\"name\":\"sxt\", \"pwd\":123},\n",
    "        \n",
    "        // 设置请求的参数为json\n",
    "        contentType:'application/json',\n",
    "        success:(data)=>{\n",
    "            console.log(data)\n",
    "        }\n",
    "    }) \n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c2695eb",
   "metadata": {},
   "source": [
    "### beforeSend 的使用"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47ff9b79",
   "metadata": {},
   "source": [
    "```js\n",
    "function test_beforsend(){\n",
    "    $.ajax({\n",
    "        type:'post',\n",
    "        url:'http://httpbin.org/post',\n",
    "        data:{\"name\":\"sxt\", \"pwd\":123},\n",
    "        \n",
    "        // 设置请求的参数为json\n",
    "        contentType:'application/json',\n",
    "        \n",
    "        success:(data)=>{\n",
    "            console.log(data)\n",
    "        },\n",
    "        \n",
    "        beforeSend:()=>{\n",
    "            console.log('这个是发送请求之前处理的内容')\n",
    "            \n",
    "            // 可以这个函数里面控制传送的条件\n",
    "            // 如果函数返回的是false将不再发送请求\n",
    "            return false\n",
    "        }\n",
    "    }) \n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18d331fd",
   "metadata": {},
   "source": [
    "## jQuery 中的 AJAX2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd0a72a6",
   "metadata": {},
   "source": [
    "具体见：AJAX/11_JQuery中使用AJAX2.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ba14ef2",
   "metadata": {},
   "source": [
    "### GET请求"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f032ad2",
   "metadata": {},
   "source": [
    "```js\n",
    "function test_get() {\n",
    "    $.get(\n",
    "        'http://httpbin.org/get',\n",
    "        function (data) {\n",
    "            console.log(data)\n",
    "        }\n",
    "    )\n",
    "}\n",
    "\n",
    "// get 请求传递str参数\n",
    "function test_get_args_str(){\n",
    "    $.get(\n",
    "        'http://httpbin.org/get',\n",
    "        'name=sxt&pwd=123',\n",
    "        function (data) {\n",
    "            console.log(data)\n",
    "        }\n",
    "    )\n",
    "}\n",
    "\n",
    "// get 请求传递json参数\n",
    "function test_get_args_json(){\n",
    "    $.get(\n",
    "        'http://httpbin.org/get',\n",
    "        {\"name\":\"sxt\",\"pwd\":123},\n",
    "        function (data) {\n",
    "            console.log(data)\n",
    "        }\n",
    "    )\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3703811e",
   "metadata": {},
   "source": [
    "### POST请求"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d47ab0e5",
   "metadata": {},
   "source": [
    "```js\n",
    "// post 请求传递str参数\n",
    "function test_post_args_str(){\n",
    "    $.post(\n",
    "        'http://httpbin.org/post',\n",
    "        'name=sxt&pwd=123',\n",
    "        function (data) {\n",
    "            console.log(data)\n",
    "        }\n",
    "    )\n",
    "}\n",
    "// post 请求传递json参数\n",
    "function test_post_args_json(){\n",
    "    $.post(\n",
    "        'http://httpbin.org/post',\n",
    "        {\"name\":\"sxt\",\"pwd\":123},\n",
    "        function (data) {\n",
    "            console.log(data)\n",
    "        }\n",
    "    )\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ec77a3dd",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a8cb0435",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "288px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
